﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System.IO;
using System.Reflection;
using System.Windows.Input;
using System.Windows;
using GameBoardViewer.Board3D;
using GameBoardViewer.Common;
using GameEngine;

namespace GameBoardViewer.Board3D
{

    public class Board3DControl : IBoard3D, IBoardControl
    {
        protected Game _game;

        protected GameBoardCheckButton m_RotationButton;
        protected GameBoardButton m_ButtonBoard;
        protected GameBoardButton m_ButtonWhite;
        protected GameBoardButton m_ButtonBlack;

        protected GameBoardModel m_GameBoardModel;
        protected GameManager m_GameManager;

        protected IBoardControl _captureControl;
        protected List<IBoardControl> childControls;
        protected IMainBoard _mainBoard;

        protected Move _currentMove;

        public event EventHandler RenderBackgroundEvent;


        public Board3DControl(Game game, IMainBoard mainBoard)
        {
            _game = game;
            _mainBoard = mainBoard;
        }

        public event GameMoveDelegate GameMoveDoneEvent;

        public bool InEditMode
        {
            get
            {
                return _mainBoard.InEditMode;
            }
        }


        public int GameBoardWidth
        {
            get { return _mainBoard.GameBoardWidth; }
        }

        public int GameBoardHeight
        {
            get { return _mainBoard.GameBoardHeight; }
        }


        public void AddMove(Move move)
        {
            if (_currentMove == null)
            {
                _currentMove = move;
            }
            else
            {
                Move lastMove = _currentMove;
                while (lastMove.nextMove != null)
                    lastMove = lastMove.nextMove;
                lastMove.nextMove = move;
            }

            if (m_GameManager.DoesMoveContinue(move, move.endPos) == false)
            {
                CallMoveDoneEvent();
            }
        }
        
        protected void CallMoveDoneEvent()
        {
            GameMoveDoneEventArgs e = new GameMoveDoneEventArgs();
            e.move = _currentMove;
            _currentMove = null;

            if (GameMoveDoneEvent != null)
            {
                GameMoveDoneEvent(this, e);
            }
        }

        public void SetData(GameManager _gameManager)
        {
            m_GameManager = _gameManager;
            if (m_GameBoardModel != null)
                m_GameBoardModel.SetData(_gameManager);
        }

        public void Initialize()
        {
            childControls = new List<IBoardControl>();

            m_RotationButton = new GameBoardCheckButton(_game, this);
            childControls.Add(m_RotationButton);

            m_ButtonBlack = new GameBoardButton(_game, this);
            m_ButtonBlack.ButtonPressed += new EventHandler(m_ButtonBlack_ButtonPressed);
            childControls.Add(m_ButtonBlack);

            m_ButtonWhite = new GameBoardButton(_game, this);
            m_ButtonWhite.ButtonPressed += new EventHandler(m_ButtonWhite_ButtonPressed);
            childControls.Add(m_ButtonWhite);

            m_ButtonBoard = new GameBoardButton(_game, this);
            m_ButtonBoard.ButtonPressed += new EventHandler(m_ButtonBoard_ButtonPressed);
            childControls.Add(m_ButtonBoard);

            // must be included after buttons, because buttons have precedence for capture
            m_GameBoardModel = new GameBoardModel(_game, this);
            m_GameBoardModel.SetData(m_GameManager);
            m_GameBoardModel.RenderBackgroundEvent += new EventHandler(m_GameBoardModel_RenderBackgroundEvent);
            childControls.Add(m_GameBoardModel);

        }

        void m_GameBoardModel_RenderBackgroundEvent(object sender, EventArgs e)
        {
            if (RenderBackgroundEvent != null)
            {
                RenderBackgroundEvent(this, EventArgs.Empty);
            }
        }

        public void LoadContent()
        {
            _captureControl = null;
            _currentMove = null;

            m_GameBoardModel.LoadContent();      

            m_RotationButton.LoadContent("Rotation", 10, 10, enumButtonDockStyle.TopRight, new Color(0, 0, 255, 128),
                        new Color(255, 255, 0, 128), new Color(255, 0, 0, 64), new Color(255, 0, 0, 128));

            m_ButtonBlack.LoadContent("ButtonBlack", 70, 10, enumButtonDockStyle.TopRight, new Color(0, 0, 255, 128),
                        new Color(255, 255, 0, 128));

            m_ButtonWhite.LoadContent("ButtonWhite", 130, 10, enumButtonDockStyle.TopRight, new Color(0, 0, 255, 128),
                        new Color(255, 255, 0, 128));

            m_ButtonBoard.LoadContent("ButtonBoard", 190, 10, enumButtonDockStyle.TopRight, new Color(0, 0, 255, 128),
                        new Color(255, 255, 0, 128));
       }

        void m_ButtonBlack_ButtonPressed(object sender, EventArgs e)
        {
            m_GameBoardModel.DoBoardRotation((float)(Math.PI / 4), (float)0);
        }

        void m_ButtonWhite_ButtonPressed(object sender, EventArgs e)
        {
            m_GameBoardModel.DoBoardRotation((float)(Math.PI / 4), (float)Math.PI);
        }

        void m_ButtonBoard_ButtonPressed(object sender, EventArgs e)
        {
            m_GameBoardModel.DoBoardRotation(0f, (float)Math.PI);
        }


        public void Update(MouseState mouse)
        {
            m_GameBoardModel.Update(mouse);
        }
       
        public void Draw()
        {           
            m_GameBoardModel.Draw();
            m_RotationButton.Draw();
            m_ButtonBlack.Draw();
            m_ButtonWhite.Draw();
            m_ButtonBoard.Draw();
        }

        public void AnimateMove(Move move)
        {
            if (m_GameBoardModel != null)
                m_GameBoardModel.AnimateMove(move);
        }

        public bool RotationChecked
        {
            get 
            {
                if (m_RotationButton == null)
                    return false;
                else
                    return m_RotationButton.IsChecked;
            }
        }

        public void SetCapture(IBoardControl control)
        {
            _captureControl = control;
            _mainBoard.SetCapture(this);
        }

        public void ReleaseCapture()
        {
            _captureControl = null;
            _mainBoard.ReleaseCapture();
        }

        public void ClickOnField(Position pos, bool leftButton)
        {
            _mainBoard.ClickOnField(pos, leftButton);
        }

        bool IBoardControl.Update(MouseState mouse)
        {
            return false;
        }

        public void OnLButtonDown(Microsoft.Xna.Framework.Point point)
        {
            if (_captureControl != null)
            {
                _captureControl.OnLButtonDown(point);
            }
            else
            {
                foreach (var item in childControls)
                {
                    // capture might be set by one of controls, then we must ignore other controls
                    if (_captureControl != null)
                        break;

                    item.OnLButtonDown(point);
                }
            }
        }

        public void OnLButtonUp(Microsoft.Xna.Framework.Point point)
        {
            if (_captureControl != null)
            {
                _captureControl.OnLButtonUp(point);
            }
            else
            {
                foreach (var item in childControls)
                {
                    item.OnLButtonUp(point);
                }
            }
        }

        public void OnMouseMoving(Microsoft.Xna.Framework.Point point)
        {
            if (_captureControl != null)
            {
                _captureControl.OnMouseMoving(point);
            }
            else
            {
                foreach (var item in childControls)
                {
                    item.OnMouseMoving(point);
                }
            }
        }

        public void OnRButtonDown(Microsoft.Xna.Framework.Point point)
        {
            if (_captureControl != null)
            {
                _captureControl.OnRButtonDown(point);
            }
            else
            {
                foreach (var item in childControls)
                {
                    item.OnRButtonDown(point);
                }
            }
        }

        public void OnRButtonUp(Microsoft.Xna.Framework.Point point)
        {
            if (_captureControl != null)
            {
                _captureControl.OnRButtonUp(point);
            }
            else
            {
                foreach (var item in childControls)
                {
                    item.OnRButtonUp(point);
                }
            }
        }
    }

}
